﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.Core.Support;
using MS.InformationManagement.DAL.DTOs;
using MS.InformationManagement.DAL.DocumentCenter;
using Microsoft.SharePoint;
using MS.InformationManagement.Support.Constants;
using Microsoft.SharePoint.Taxonomy;
using MS.InformationManagement.Core.TransactionsResponse;

namespace MS.InformationManagement.BLL.DocumentPrinter
{
    public class CreateDeliveryMailCommand : IBaseCommand
    {

        #region Fields

        EnvíoDeCorrespondenciaDTO[] _deliveries;

        #endregion

        #region Constructors

        public CreateDeliveryMailCommand(EnvíoDeCorrespondenciaDTO[] deliveries)
        {
            _deliveries = deliveries;
        }

        #endregion

        public void Execute()
        {
            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                List<EnvíoDeCorrespondencia> entities = new List<EnvíoDeCorrespondencia>();
                List<KeyValuePair<int, EnvíoDeCorrespondencia>> references = new List<KeyValuePair<int, EnvíoDeCorrespondencia>>();

                foreach (EnvíoDeCorrespondenciaDTO delivery in _deliveries)
                {
                    var entity = GetObjectFromDTO(delivery, DateTime.Now, ctx);
                    entities.Add(entity);
                }

                if (entities.Count > 0)
                {
                    ctx.EnviosDeCorreo.InsertAllOnSubmit(entities);
                    ctx.SubmitChanges();
                   
                    //Get reference to create lookups from window reception to deliveries list
                    foreach (EnvíoDeCorrespondencia entity in entities)
                    { 
                        int currenItemId = getWindowReceptionItemId(entity.NoRadicado.ToString(),entity.BibliotecaDelDocumento);
                        references.Add(new KeyValuePair<int,EnvíoDeCorrespondencia>(currenItemId, entity));
                    }

                    //Update window reception references
                    updateParentItem(references);
                }
            }
        }

        public void Undo()
        {
        }

        #region Private Methods

        private int getWindowReceptionItemId(string docId, string libraryName)
        {
            SPList windowReception = SPContext.Current.Web.Lists.TryGetList(GlobalConstants.LIST_DOCUMENTOS_VENTANILLA);
            if (windowReception == null)
                throw new Exception(string.Format(ExceptionConstants.ERROR_LISTA_INEXISTENTE, GlobalConstants.LIST_DOCUMENTOS_VENTANILLA));
            SPQuery query = new SPQuery();
            query.Query =string.Format(@"<Where>
                                            <And>
                                                <Eq>
                                                    <FieldRef Name='Document_Radicado' />
                                                    <Value Type='Text'>{0}</Value>
                                                </Eq>
                                                <Eq>
                                                    <FieldRef Name='LibraryName' />
                                                    <Value Type='Text'>{1}</Value>
                                                </Eq>
                                            </And>
                                          </Where>", docId, libraryName);
            query.RowLimit = 1; 
            SPListItemCollection listItem = windowReception.GetItems(query);
            if (listItem.Count == 0)
                throw new Exception(string.Format(ExceptionConstants.ERROR_ITEM_NO_ENCONTRADO, "En ventana recepción no encontrado"));
            return listItem[0].ID;
        }

        private void updateParentItem(List<KeyValuePair<int, EnvíoDeCorrespondencia>> envios)
        { 
            foreach(var entity in envios)
            {
                SPFieldLookupValue lookUpValue = new SPFieldLookupValue(entity.Value.Id.Value, entity.Value.Title);
                IBaseCommand updateDelivery = new UpdateReceivedDocumentWindow(lookUpValue,entity.Key);
                updateDelivery.Execute();
            }
        }

        private static EnvíoDeCorrespondencia GetObjectFromDTO(EnvíoDeCorrespondenciaDTO delivery, DateTime deliveryDate, DCDocumentCenterDataContext context)
        {
            SPList targetList = SPContext.Current.Web.Lists.TryGetList(delivery.LibraryName);
            if (targetList == null) { throw new Exception(string.Format("La biblioteca {0} no existe", delivery.LibraryName)); }

            SPListItem targetItem = targetList.GetItemById(delivery.DocumentId);
            if (targetItem == null) { throw new Exception(string.Format("El radicado con id {0} en la biblioteca {1} no existe", delivery.DocumentId, delivery.LibraryName)); }

            string destinatario = targetItem[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT] == null ? string.Empty : targetItem[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT].ToString();

            if (targetItem.ContentType.Name == GlobalConstants.CTTN_COPIAS_RADICADO)
            { 
                destinatario = targetItem[CustomSiteColumns.FLD_COPY_REPRESENTANTE] == null ? targetItem[CustomSiteColumns.FLD_COPY_NAME].ToString() : targetItem[CustomSiteColumns.FLD_COPY_REPRESENTANTE].ToString(); 
                targetItem = targetItem.File.ParentFolder.Item; 
            }

            MedioDeEnvio deliveryMean = GetDeliveryMean(delivery.DeliveryMeanId, context);
            Zona deliveryZone = GetDeliveryZone(delivery.DeliveryZone, context);

            EnvíoDeCorrespondencia entity = new EnvíoDeCorrespondencia
            {
                CostoDelEnvío = delivery.DeliveryCost,
                MedioEnvioCorreo = deliveryMean,
                Dirección = targetItem[CustomSiteColumns.FIELD_DOCUMENT_ADDRESS].ToString(),
                Email = targetItem[CustomSiteColumns.FIELD_DOCUMENT_EMAIL].ToString(),
                FechaDeEnvío = deliveryDate,
                PesoCorrespondencia = delivery.Weight,
                RemitenteDestinatario = targetItem[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT].ToString(),
                Teléfono = targetItem[CustomSiteColumns.FIELD_DOCUMENT_PHONE].ToString(),
                Title = string.Format("Envio de correspondencia para el documento {0}", delivery.DocumentNumber),
                City = targetItem[CustomSiteColumns.FIELD_DOCUMENT_COUNTRY] as TaxonomyFieldValue,
                BibliotecaDelDocumento = delivery.LibraryName,
                IdDocumento = delivery.DocumentId,     
                EnvioLocal = delivery.IsLocalDelivery,
                EnvioNacional = delivery.IsNationalDelivery,
                NoRadicado = delivery.DocumentNumber,
                ZonaEnvio = deliveryZone,
                Copia = delivery.IsCopy
            };
            return entity;
        }

        private static MedioDeEnvio GetDeliveryMean(int deliveryMeanId, DCDocumentCenterDataContext context)
        {
            MedioDeEnvio entity = null;
            entity = context.MediosDeEnvio.SingleOrDefault(deliveryMean => deliveryMean.Id.Equals(deliveryMeanId));
            if (entity == default(MedioDeEnvio)) { throw new Exception(string.Format("El medio de envio con id {0} no existe", deliveryMeanId)); }
            return entity;
        }

        private static Zona GetDeliveryZone(int deliveryZone, DCDocumentCenterDataContext context)
        {
            return context.Zonas.FirstOrDefault(deliveryMean => deliveryMean.Id.Equals(deliveryZone));
        }


        #endregion


    }
}
